#ifndef __MY_HASH__
#define __MY_HASH__

#include <iostream>
#include <iomanip>
#include <openssl/sha.h>
#include <openssl/evp.h>


class Hash 
{
public:
    enum HashType 
    {
        SHA224_TYPE,
        SHA256_TYPE,
        SHA384_TYPE,
        SHA512_TYPE,
    };

    explicit Hash(HashType type);
    ~Hash();

    int Update(const void* data, size_t len);
    std::string Final();
    static std::string GetHash(HashType type, const unsigned char* data, size_t len);
    static std::string ToHex(const unsigned char* data, size_t len);
private:
    Hash(const Hash&) = delete;
    Hash& operator=(const Hash&) = delete;

    static const EVP_MD* _GetDigest(HashType type);

private:
    EVP_MD_CTX* _ctx;
};



/*
EVP_MD_CTX_new：用于创建一个新的 EVP_MD_CTX 结构体实例，用于存储消息摘要操作的上下文信息 如果分配失败则返回 NULL。
EVP_MD_CTX 结构体用于存储消息摘要操作的上下文信息，包括当前使用的 EVP_MD 算法和状态信息。


EVP_MD：表示一种消息摘要算法，封装了算法的相关信息。
EVP_MD 结构体在 OpenSSL 中用于表示一种消息摘要(hash)算法。它包含了算法的名称、块大小、输出大小等信息。
EVP_MD 结构体提供了一种抽象的方式来处理不同的消息摘要算法，使得用户可以在不改变代码结构的情况下切换不同的算法。


EVP_DigestInit_ex：用于初始化一个 EVP_MD_CTX 结构体实例，以便进行消息摘要操作，需要指定使用的消息摘要算法。
该函数接受三个参数：一个指向 EVP_MD_CTX 结构体的指针、一个指向 EVP_MD 结构体的指针（表示要使用的消息摘要算法）和一个可选的引擎指针（通常设置为 NULL）。
*/

#endif // __MY_HASH__
